#pragma once

#include <../server/Logger.h>
#include <string>
#include <unordered_map>

// Request instance:
// POST /aichat/api/follow_card?query=C++&token=3262c13b514e19a136905d03bdaf4aa3 HTTP/1.1
// Accept: */*
// Accept-Encoding: gzip, deflate, br, zstd
// Accept-Language: zh-CN,zh;q=0.9
// Connection: keep-alive
// Content-Length: 65
// Content-Type: application/json
// Cookie: PSTM=1...7jFDzFOw66zCw:C
// Host: chat.baidu.com
// Origin: https://www.baidu.com
// Referer: https://www.baidu.com/
// Sec-Fetch-Dest: empty
// Sec-Fetch-Mode: cors
// Sec-Fetch-Site: same-site
// User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0
// Safari/537.36 sec-ch-ua: "Google Chrome";v="123", "Not:A-Brand";v="8", "Chromium";v="123" sec-ch-ua-mobile: ?0
// sec-ch-ua-platform: "Windows"
// \n
// {"query":"C++","cacheKey":"pc_right_follow_16574177794813701018"}

/*
请求方法  URL  HTTP版本号
请求报头
\n
请求正文
*/

class Request {
public:
    Request() : version_("HTTP/1.1") {}

    void Reset() {
        method_.clear();
        url_.clear();
        version_ = "HTTP/1.1";
        kvs_.clear();
        body_.clear();
    }

    void SetMethod(std::string method) { method_ = method; }
    void SetUrl(std::string url) { url_ = url; }
    void SetVersion(std::string version) { version_ = version; }
    void SetBody(std::string body) { body_ = body; }

    void AddHeader(std::string key, std::string value) { kvs_.insert(std::make_pair(key, value)); }

    bool HasKey(const std::string& key) { return kvs_.find(key) != kvs_.end(); }

    std::string GetValue(const std::string& key) {
        if (HasKey(key))
            return kvs_[key];
    }

    bool SetValue(const std::string& key, const std::string& value) {
        if (HasKey(key))
            kvs_[key] = value;
    }

    int ContentLength() {
        if (HasKey("Content-Length")) {
            LOG_INFO("get content length:%s", kvs_["Content-Length"].c_str());
            return std::stol(kvs_["Content-Length"]);
        } else
            return 0;
    }

    std::string Print() {
        std::string req_str;
        req_str = method_ + " " + url_ + " " + version_ + "\r\n";
        for (auto& kv : kvs_) {
            std::string head = kv.first + ": " + kv.second + "\r\n";
            req_str += head;
        }
        req_str += "\r\n";
        return req_str;
    }

    // private:
    std::string method_;
    std::string url_;
    std::string version_;
    std::unordered_map<std::string, std::string> kvs_;
    std::string body_;
};
